import html2canvas from "html2canvas";
import { downloadByA } from "./file";
import throttle from "lodash/throttle";
import cloneDeep from "lodash/cloneDeep";

/**
 * * 判断是否是开发环境
 * @return { Boolean }
 */
export const isDev = () => {
  return import.meta.env.DEV;
};

/**
 * * 生成一个不重复的ID
 * @param { Number } randomLength
 */
export const getUUID = (randomLength = 10) => {
  return Number(
    Math.random().toString().substring(2, randomLength) + Date.now()
  ).toString(36);
};

/**
 * * 截取画面为图片并下载
 * @param html 需要截取的 DOM
 */
export const canvasCut = (html, callback) => {
  if (!html) {
    if (callback) callback();
    return;
  }

  html2canvas(html, {
    backgroundColor: null,
    allowTaint: true,
    useCORS: true,
  }).then((canvas) => {
    downloadByA(canvas.toDataURL(), undefined, "png");
    if (callback) callback();
  });
};

export const JSONStringify = (data) => {
  return JSON.stringify(
    data,
    (key, val) => {
      // 处理函数丢失问题
      if (typeof val === "function") {
        return `${val}`;
      }
      // 处理 undefined 丢失问题
      if (typeof val === "undefined") {
        return null;
      }
      return val;
    },
    2
  );
};

export const evalFn = (fn) => {
  var Fun = Function; // 一个变量指向Function，防止前端编译工具报错
  return new Fun("return " + fn)();
};

// 内置字符串函数对象列表
export const excludeParseEventKeyList = [
  "vnodeMounted",
  "vnodeBeforeMount",
  "click",
  "dblclick",
  "mouseenter",
  "mouseleave",
  //过滤器
  "filter",
];
// 内置字符串函数键值列表
export const excludeParseEventValueList = [
  // 请求里的函数语句
  "javascript:",
];

/**
 * * JSON反序列化，支持函数和 undefined
 * @param data
 */
export const JSONParse = (data) => {
  return JSON.parse(data, (k, v) => {
    // 过滤函数字符串
    if (excludeParseEventKeyList.includes(k)) return v;
    // 过滤函数值表达式
    if (typeof v === "string") {
      const someValue = excludeParseEventValueList.some(
        (excludeValue) => v.indexOf(excludeValue) > -1
      );
      if (someValue) return v;
    }
    // 还原函数值
    if (
      typeof v === "string" &&
      v.indexOf &&
      (v.indexOf("function") > -1 || v.indexOf("=>") > -1)
    ) {
      return evalFn(`(function(){return ${v}})()`);
    } else if (
      typeof v === "string" &&
      v.indexOf &&
      v.indexOf("return ") > -1
    ) {
      const baseLeftIndex = v.indexOf("(");
      if (baseLeftIndex > -1) {
        const newFn = `function ${v.substring(baseLeftIndex)}`;
        return evalFn(`(function(){return ${newFn}})()`);
      }
    }
    return v;
  });
};

/**
 * * 挂载监听
 */
export const addEventListener = (target, type, listener, delay, options) => {
  if (!target) return;
  target.addEventListener(
    type,
    throttle(listener, delay || 300, {
      leading: true,
      trailing: false,
    }),
    options
  );
};

/**
 * * 卸载监听
 */
export const removeEventListener = (target, type, listener) => {
  if (!target) return;
  target.removeEventListener(type, listener);
};

export function formartJsonStr(text_value) {
  if (text_value == "") {
    alert("不能为空");
    return "";
  } else {
    let res = "";
    for (let i = 0, j = 0, k = 0, ii, ele; i < text_value.length; i++) {
      //k:缩进，j:""个数
      ele = text_value.charAt(i);
      if (j % 2 == 0 && ele == "}") {
        k--;
        for (ii = 0; ii < k; ii++) ele = "    " + ele;
        ele = "\n" + ele;
      } else if (j % 2 == 0 && ele == "{") {
        ele += "\n";
        k++;
        // debugger;
        for (ii = 0; ii < k; ii++) ele += "    ";
      } else if (j % 2 == 0 && ele == ",") {
        ele += "\n";
        for (ii = 0; ii < k; ii++) ele += "    ";
      } else if (ele == '"') j++;
      res += ele;
    }
    return res;
  }
}

export const newFunctionHandle = (
  data,
  res,
  funcStr,
  isToString,
  errorCallBack,
  successCallBack
) => {
  try {
    if (!funcStr) return data;
    const fn = new Function("data", "res", funcStr);
    const fnRes = fn(cloneDeep(data), cloneDeep(res));
    const resHandle = isToString ? toString(fnRes) : fnRes;
    // 成功回调
    successCallBack && successCallBack(resHandle);
    return resHandle;
  } catch (error) {
    // 失败回调
    errorCallBack && errorCallBack(error);
    return "函数执行错误";
  }
};

export const intervalUnitHandle = (num, unit) => {
  switch (unit) {
    // 秒
    case "second":
      return num * 1000;
    // 分
    case "minute":
      return num * 1000 * 60;
    // 时
    case "hour":
      return num * 1000 * 60 * 60;
    // 天
    case "day":
      return num * 1000 * 60 * 60 * 24;
    default:
      return num * 1000;
  }
};

/**
 *
 * @param {string} obj 对象
 * 对象转数组方法
 * @returns
 */
export function objToArray(obj) {
  let arr = [];
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      const item = obj[key];
      item.key = key;
      arr.push(item);
    }
  }
  return arr;
}
export const formatTime = (time, type = "YYYY-MM-DD HH:mm:ss") => {
  if (typeof time === "number" && time.length === 10) {
    // 解析 Unix 时间戳 (秒) 1666617034
    // dayjs.unix().format('YYYY-MM-DD')
    // 时间戳 (秒)转为毫秒
    time = time * 1000;
  }
  // 解析 Date 对象实例 new Date()
  // 解析 Unix 时间戳 (毫秒) 1666617034000
  // 解析符合 ISO 8601 格式的日期字符串 '2022-10-24T20:00:00.000Z'
  return dayjs(time).format(type);
};
